﻿using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

namespace SimbaRGVMonitor.Common.Data
{
    [Serializable]
    public class ReadOnlyDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
    {
        public ReadOnlyDictionary()
            : this(new Dictionary<TKey, TValue>())
        {

        }

        public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
        {
            container = new Dictionary<TKey, TValue>(dictionary);
        }

        //====================================================================================================
        //以上是类型构造函数
        //----------------------------------------------------------------------------------------------------
        //以下是类型字段
        //====================================================================================================

        private readonly Dictionary<TKey, TValue> container;
        private readonly object syncThreadLock = new object();

        //====================================================================================================
        //以上是类型字段
        //----------------------------------------------------------------------------------------------------
        //以下是类型属性
        //====================================================================================================

        public int Count
        {
            get
            {
                lock (syncThreadLock)
                {
                    return container.Count;
                }
            }
        }

        public TValue this[TKey key]
        {
            get
            {
                lock (syncThreadLock)
                {
                    return container[key];
                }
            }
        }

        public KeyValuePair<TKey, TValue> this[int index]
        {
            get
            {
                lock (syncThreadLock)
                {
                    return container.ElementAt(index);
                }
            }
        }

        public TKey[] Keys
        {
            get
            {
                lock (syncThreadLock)
                {
                    return container.Keys.ToArray();
                }
            }
        }

        public TValue[] Values
        {
            get
            {
                lock (syncThreadLock)
                {
                    return container.Values.ToArray();
                }
            }
        }

        //====================================================================================================
        //以上是查询接口
        //----------------------------------------------------------------------------------------------------
        //以下是字典操作
        //====================================================================================================

        public bool ContainsKey(TKey key)
        {
            lock (syncThreadLock)
            {
                return container.ContainsKey(key);
            }
        }

        public bool TryGetValue(TKey key, out TValue value)
        {
            lock (syncThreadLock)
            {
                return container.TryGetValue(key, out value);
            }
        }

        //====================================================================================================
        //以上是字典操作
        //----------------------------------------------------------------------------------------------------
        //以下是字典交互接口
        //====================================================================================================

        protected void AddCore(TKey key, TValue value)
        {
            lock (syncThreadLock)
            {
                container.Add(key, value);
            }
        }

        protected bool RemoveCore(TKey key)
        {
            lock (syncThreadLock)
            {
                return container.Remove(key);
            }
        }

        protected void AddOrUpdateCore(TKey key, TValue value)
        {
            lock (syncThreadLock)
            {
                container[key] = value;
            }
        }

        protected T RunWithContainer<T>(Func<Dictionary<TKey, TValue>, T> func)
        {
            lock (syncThreadLock)
            {
                return func(container);
            }
        }

        protected void RunWithContainer(Action<Dictionary<TKey, TValue>> action)
        {
            lock (syncThreadLock)
            {
                action(container);
            }
        }

        //====================================================================================================
        //以上是字典交互接口
        //----------------------------------------------------------------------------------------------------
        //以下是迭代器的具体实现
        //====================================================================================================

        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
        {
            lock (syncThreadLock)
            {
                return container.GetEnumerator();
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        //====================================================================================================
        //以上是迭代器的具体实现
        //----------------------------------------------------------------------------------------------------
        //以下是重写ToString
        //====================================================================================================

        public override string ToString()
        {
            return string.Format("数量={0}", Count);
        }
    }
}
